import {Condition} from "../conditions";

// ----------- 公共类型 -----------

/**
 * 数据类型枚举
 *
 * - INTEGER: 整数类型
 * - TEXT: 文本类型
 * - REAL: 浮点数类型
 * - BLOB: 二进制类型
 */
export type TableDataType = 'INTEGER' | 'TEXT' | 'REAL' | 'BLOB';

/**
 * 数据类型常量
 */
export const TABLE_DATA_TYPE = {
  INTEGER: 'INTEGER' as TableDataType,
  TEXT: 'TEXT' as TableDataType,
  REAL: 'REAL' as TableDataType,
  BLOB: 'BLOB' as TableDataType
};

/**
 * SQL操作类型枚举
 *
 * - SELECT: 查询操作
 * - INSERT: 插入操作
 * - UPDATE: 更新操作
 * - DELETE: 删除操作
 */
export type SqlOperationType = 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE';

/**
 * SQL操作类型常量
 */
export const SQL_OPERATION_TYPE = {
  SELECT: 'SELECT' as SqlOperationType,
  INSERT: 'INSERT' as SqlOperationType,
  UPDATE: 'UPDATE' as SqlOperationType,
  DELETE: 'DELETE' as SqlOperationType
};

/**
 * 条件操作符枚举
 *
 * - EQ: 等于(=)
 * - NE: 不等于(<>)
 * - GT: 大于(>)
 * - GTE: 大于等于(>=)
 * - LT: 小于(<)
 * - LTE: 小于等于(<=)
 * - LIKE: 模糊匹配(LIKE)
 * - NOT_LIKE: 模糊匹配取反(NOT LIKE)
 * - IN: 包含(IN)
 * - NOT_IN: 不包含(NOT IN)
 * - IS_NULL: 为空(IS NULL)
 * - IS_NOT_NULL: 不为空(IS NOT NULL)
 * - BETWEEN: 区间(BETWEEN)
 * - NOT_BETWEEN: 不在区间(NOT BETWEEN)
 * - EXISTS: 存在子查询(EXISTS)
 * - NOT_EXISTS: 不存在子查询(NOT EXISTS)
 * - RAW: 原始SQL片段
 */
export type ConditionOperator =
  | '='
  | '<>'
  | '>'
  | '>='
  | '<'
  | '<='
  | 'LIKE'
  | 'NOT LIKE'
  | 'IN'
  | 'NOT IN'
  | 'IS NULL'
  | 'IS NOT NULL'
  | 'BETWEEN'
  | 'NOT BETWEEN'
  | 'EXISTS'
  | 'NOT EXISTS'
  | 'RAW';

/**
 * 条件操作符常量
 */
export const CONDITION_OPERATOR = {
  EQ: '=' as ConditionOperator,
  NE: '<>' as ConditionOperator,
  GT: '>' as ConditionOperator,
  GTE: '>=' as ConditionOperator,
  LT: '<' as ConditionOperator,
  LTE: '<=' as ConditionOperator,
  LIKE: 'LIKE' as ConditionOperator,
  NOT_LIKE: 'NOT LIKE' as ConditionOperator,
  IN: 'IN' as ConditionOperator,
  NOT_IN: 'NOT IN' as ConditionOperator,
  IS_NULL: 'IS NULL' as ConditionOperator,
  IS_NOT_NULL: 'IS NOT NULL' as ConditionOperator,
  BETWEEN: 'BETWEEN' as ConditionOperator,
  NOT_BETWEEN: 'NOT BETWEEN' as ConditionOperator,
  EXISTS: 'EXISTS' as ConditionOperator,
  NOT_EXISTS: 'NOT EXISTS' as ConditionOperator,
  RAW: 'RAW' as ConditionOperator
};

/**
 * 逻辑操作符枚举
 *
 * - AND: 与
 * - OR: 或
 */
export type LogicalOperator = 'AND' | 'OR';

/**
 * 逻辑操作符常量
 */
export const LOGICAL_OPERATOR = {
  AND: 'AND' as LogicalOperator,
  OR: 'OR' as LogicalOperator
};

/**
 * 排序方向枚举
 *
 * - ASC: 升序
 * - DESC: 降序
 */
export type OrderDirection = 'ASC' | 'DESC';

/**
 * 排序方向常量
 */
export const ORDER_DIRECTION = {
  ASC: 'ASC' as OrderDirection,
  DESC: 'DESC' as OrderDirection
};

/**
 * 联接类型枚举
 *
 * - INNER: 内联接
 * - LEFT: 左外联接
 * SQLite不支持RIGHT JOIN和FULL JOIN
 */
export type JoinType = 'INNER JOIN' | 'LEFT JOIN';

/**
 * 联接类型常量
 */
export const JOIN_TYPE = {
  INNER: 'INNER JOIN' as JoinType,
  LEFT: 'LEFT JOIN' as JoinType
};

/**
 * 实体类字段映射接口
 */
export interface EntityFieldMapping {
  /** 实体类中的属性名 */
  propertyName: string;
  /** 数据库表中的字段名 */
  columnName: string;
  /** 数据类型 */
  dataType?: string;
  /** 是否为主键 */
  isPrimaryKey?: boolean;
  /** 是否自动递增 */
  isAutoIncrement?: boolean;
  /** 是否允许为空 */
  isNullable?: boolean;
  /** 默认值 */
  defaultValue?: any;
}

/**
 * 表实体映射接口
 */
export interface TableEntityMapping {
  /** 表名 */
  tableName: string;
  /** 主键字段名称 */
  primaryKey?: string;
  /** 字段映射 */
  fields: Record<string, EntityFieldMapping>;
}

/**
 * SQL排序接口
 */
export interface OrderBy {
  /** 排序字段 */
  field: string;
  /** 排序方向 */
  direction: OrderDirection;
}

/**
 * 联接条件接口
 */
export interface JoinCondition {
  /** 联接类型 */
  type: JoinType;
  /** 联接表名 */
  table: string;
  /** 联接表别名 */
  alias?: string;
  /** 联接条件 */
  on: Condition | Condition[];
  /** 表实体映射 */
  entityMapping?: TableEntityMapping;
}

/**
 * SQL构建结果接口
 */
export interface SqlBuildResult {
  /** SQL语句 */
  sql: string;
  /** 参数对象 */
  params: Record<string, any>;
}

/**
 * 表构建结果接口
 * 扩展了SqlBuildResult，增加了索引SQL语句数组
 */
export interface TableBuildResult extends SqlBuildResult {
  /** 索引SQL语句数组 */
  indexSqls: string[];
}

/**
 * 实体类型
 * 泛型T代表实体对象的类型
 */
export type Entity<T = any> = {
  [P in keyof T]: T[P];
};

/**
 * 查询字段选择类型
 * T代表实体类型，K代表字段名称
 */
export type FieldSelection<T> = Array<keyof T | string | '*'>;

/**
 * 查询结果类型
 * 为查询结果提供类型安全
 */
export type QueryResult<T> = T[];

/**
 * 单行查询结果类型
 */
export type SingleResult<T> = T | undefined;

/**
 * 字段更新对象类型
 */
export type UpdateFields<T> = Partial<{
  [P in keyof T]: T[P];
}>;

/**
 * SQL扩展配置接口
 * 用于为SQL构建器提供扩展点
 */
export interface SqlBuilderExtensions {
  /** 自定义字段处理器 */
  fieldProcessors?: Array<(field: string, context: any) => string>;
  /** 自定义值处理器 */
  valueProcessors?: Array<(value: any, context: any) => any>;
  /** 自定义SQL钩子 */
  sqlHooks?: {
    beforeBuild?: (context: any) => void;
    afterBuild?: (result: SqlBuildResult, context: any) => SqlBuildResult;
  };
}

// ----------- TableBuilder 表构建器类型 -----------

/**
 * 引用操作类型
 *
 * - CASCADE: 级联操作
 * - RESTRICT: 严格限制，如果存在引用则阻止操作
 * - SET NULL: 将引用字段设置为NULL
 * - SET DEFAULT: 将引用字段设置为默认值
 * - NO ACTION: 不执行任何操作（类似于RESTRICT）
 */
export type ReferenceAction = 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'SET DEFAULT' | 'NO ACTION';

/**
 * 表字段定义
 * 用于定义数据库表的列信息
 * @template T 表对应的实体类型
 * @template R 引用表的实体类型
 */
export interface TableColumn<T = any, R = any> {
  /** 字段名称 */
  name: Extract<keyof T, string> | string;

  /** 字段数据类型，如INTEGER、TEXT、REAL、BLOB等 */
  type: TableDataType;

  /** 是否为主键，设置为true时该字段将成为表的主键 */
  primaryKey?: boolean;

  /** 是否自动递增，仅适用于INTEGER类型的主键字段 */
  autoIncrement?: boolean;

  /** 是否不允许为NULL，设置为true时该字段不能存储NULL值 */
  notNull?: boolean;

  /** 是否唯一，设置为true时该字段的值在表中必须唯一 */
  unique?: boolean;

  /** 字段的默认值，当插入数据未提供该字段值时使用 */
  defaultValue?: any;

  /** 字段检查约束条件，用于验证该字段的值是否满足指定条件 */
  check?: string;

  /** 外键引用信息，用于建立与其他表的关联关系 */
  references?: {
    /** 引用的表名 */
    table: string;

    /** 引用的列名 */
    column: Extract<keyof R, string> | string;

    /** 当被引用行更新时的操作 */
    onUpdate?: ReferenceAction;

    /** 当被引用行删除时的操作 */
    onDelete?: ReferenceAction;
  }
}

/**
 * 时间戳选项
 * @template T 表对应的实体类型
 */
export interface TimestampsOptions<T = any> {
  /**
   * 创建时间列名，默认为created_at
   */
  createdAt?: Extract<keyof T, string> | string;

  /**
   * 更新时间列名，默认为updated_at
   */
  updatedAt?: Extract<keyof T, string> | string;

  /**
   * 是否使用毫秒级时间戳，默认为false
   * 如果为true，将使用strftime('%s') || '000'作为默认值
   * 如果为false，将使用CURRENT_TIMESTAMP作为默认值
   */
  useMilliseconds?: boolean;

  /**
   * 是否设置为非空，默认为true
   */
  notNull?: boolean;
}

/**
 * 软删除选项
 * @template T 表对应的实体类型
 */
export interface SoftDeleteOptions<T = any> {
  /**
   * 删除时间列名，默认为deleted_at
   */
  deletedAt?: Extract<keyof T, string> | string;

  /**
   * 是否使用毫秒级时间戳，默认为false
   */
  useMilliseconds?: boolean;

  /**
   * 是否设置为非空，默认为false
   */
  notNull?: boolean;
}

/**
 * 索引定义
 * @template T 表对应的实体类型
 */
export interface TableIndex<T = any> {
  /** 索引名称 */
  name: string;
  /** 列名数组 */
  columns: Array<Extract<keyof T, string> | string>;
  /** 是否唯一 */
  unique?: boolean;
}

/**
 * 表定义接口，用于JSON配置
 * @template T 表对应的实体类型
 */
export interface TableDefinition<T = any> {
  /** 表名 */
  name: string;
  /** 列定义 */
  columns: TableColumn<T>[];
  /** 索引定义 */
  indices?: TableIndex<T>[];
  /** 是否为临时表 */
  temporary?: boolean;
  /** 是否不存在则创建 */
  ifNotExists?: boolean;
  /** 表备注 */
  comment?: string;
}
